﻿using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using log4net.Config;
using Spark.Web.Mvc;
using Wayloop.Blog.DependencyResolution;
using Wayloop.Web.Mvc.Extensions;
using Wayloop.Web.Mvc.Models.Validation;


namespace Wayloop.Blog.Presentation.UI
{
    public class MvcApplication : HttpApplication
    {
        /// <summary>
        /// Registers the routes.
        /// </summary>
        /// <param name="routes">The routes.</param>
        public void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            //
            // ADMIN ROUTES
            // ============
            routes
                .MapArea("Admin", "Wayloop.Blog.Presentation.Controllers.Admin")
                .WithRoutes(area => {
                    area.AddRoute(
                        "admin/login",
                        new { controller = "User", action = "Login" }
                        );

                    area.AddRoute(
                        "admin/comments/{commentStatus}/{pageNumber}",
                        new { controller = "Comment", action = "List", pageNumber = "" },
                        new { commentStatus = @"[a-z]+", pageNumber = @"\d*" }
                        );

                    area.AddRoute(
                        "admin/comments/{pageNumber}",
                        new { controller = "Comment", action = "List", pageNumber = "" },
                        new { pageNumber = @"\d*" }
                        );

                    area.AddRoute(
                        "admin/{controller}/{action}/{id}",
                        new { controller = "Post", action = "Index", id = "" }
                        );
                });

            //
            // ROOT ROUTES
            // ===========
            routes
                .MapRootArea("Wayloop.Blog.Presentation.Controllers")
                .WithRoutes(area => {
                    area.AddRoute(
                        "archive/{slug}/{action}",
                        new { controller = "Post" },
                        new { action = "AddComment" }
                        );

                    area.AddRoute(
                        "archive/{slug}",
                        new { controller = "Post", action = "Show" }
                        );

                    area.AddRoute(
                        "archive",
                        new { controller = "Post", action = "Archive" }
                        );

                    area.AddRoute(
                        "{controller}/{action}",
                        new { controller = "Post", action = "Index" }
                        );
                });
        }


        /// <summary>
        /// Registers the controller factory.
        /// </summary>
        public void RegisterControllerFactory(ControllerBuilder builder)
        {
            builder.SetControllerFactory(new ControllerFactory());
        }


        /// <summary>
        /// Registers the view engine.
        /// </summary>
        public void RegisterViewEngine(ICollection<IViewEngine> viewEngines)
        {
            viewEngines.Clear();
            SparkEngineStarter.RegisterViewEngine(viewEngines);
        }


        /// <summary>
        /// Registers the model binders.
        /// </summary>
        public void RegisterModelBinders(ModelBinderDictionary modelBinders)
        {
            modelBinders.DefaultBinder = new ValidatingModelBinder();
        }


        /// <summary>
        /// Initializes the logging service.
        /// </summary>
        private void InitializeLoggingService()
        {
            XmlConfigurator.Configure();
        }


        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
            RegisterControllerFactory(ControllerBuilder.Current);
            RegisterViewEngine(ViewEngines.Engines);
            RegisterModelBinders(ModelBinders.Binders);

            InitializeLoggingService();
        }
    }
}